var api = require('../config/api.js');
import WxRequest from '../lib/wx-request/lib/index'

function formatTime(date) {
  var year = date.getFullYear()
  var month = date.getMonth() + 1
  var day = date.getDate()

  var hour = date.getHours()
  var minute = date.getMinutes()
  var second = date.getSeconds()


  return [year, month, day].map(formatNumber).join('-') + ' ' + [hour, minute, second].map(formatNumber).join(':')
}

function formatNumber(n) {
  n = n.toString()
  return n[1] ? n : '0' + n
}

function generateUUID() {
  var d = new Date().getTime();
  var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
    var r = (d + Math.random() * 16) % 16 | 0;
    d = Math.floor(d / 16);
    return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
  });
  return uuid;
};

var arrayUtil = function () {
  return {
    delByIndex: function (arr, i) {
      var newArr = arr.slice(0);
      newArr.splice(i, 1);
      return newArr;
    },
    combind: function (a, b) { //a,b不变,返回一个新的数组，占用内存
      return a.concat(b);
    },
    //for循环很土并且难以维护
    combindByFor: function (a, b) {//push 向后继续添加，unshift 向前插入
      if (a.length > b.length) {
        for (var i = 0; i < b.length; i++) {
          a.push(b[i]);
        }
        return a;
      } else {
        for (var i = 0; i < a.length; i++) {
          b.push(a[i]);
        }
        return b;
      }
    },
    reduce: function (a, b) {
      a = b.reduce(function (coll, item) {
        coll.push(item);
        return coll;
      }, a);
      return a;
    },
    reduceRight: function (a, b) {
      b = a.reduceRight(function (coll, item) {
        coll.unshift(item);
        return coll;
      }, b);
      return b;
    },
    //实际上数组都会被打散成为函数的 arguments 引擎有不同的实现算法,可能会限制了函数可以传递的参数数量
    apply: function (a, b) {
      a.push.apply(a, b);
    },
    unshift: function (a, b) {
      b.push.unshift(b, a);
    },
    sort: function (raws, type) {
      if (type == 'date') {
        return raws.sort(function (a, b) { return new Date(a).getTime() - new Date(b).getTime() });
      } else if (type == 'num') {
        return raws.sort(function (a, b) { return Number(a) - Number(b) });
      }
    },
    combineInto: function (a, b) {
      var len = a.length;
      for (var i = 0; i < len; i = i + 5000) {
        // 一次处理5000条
        b.unshift.apply(b, a.slice(i, i + 5000));
      }
    },
    copy(obj) {
      var newobj = {};
      for (var attr in obj) {
        newobj[attr] = obj[attr];
      }
      return newobj;
    },
    deepCopy(obj) {
      if (typeof obj != 'object') {
        return obj;
      }
      var newobj = {};
      for (var attr in obj) {
        newobj[attr] = deepCopy(obj[attr]);
      }
      return newobj;
    },
    assign(isDeep, obj) {
      return isDeep ? this.deepCopy.apply(this, obj) : this.copy.apply(this, obj);
    }
  };
}();

var dateUtil = function () {
  return {
    currentDateString: function (date) {
      if (!date)
        date = new Date();
      var y = date.getFullYear();
      var m = date.getMonth() + 1;
      var d = date.getDate();
      return y + '-' + (m < 10 ? ('0' + m) : m) + '-' + (d < 10 ? ('0' + d) : d);
    }
  };
}();

let confirm = {
  config: {
    content: '',
    confirmText: "确定",
    cancelText: "取消",
    success: function (res) {
      if (res.confirm) {
        console.log('用户点击主操作')
      } else {
        console.log('用户点击辅助操作')
      }
    }
  },
  common: function (opt) {
    let changeOp = Object.assign({}, this.config, opt);
    wx.showModal(changeOp);
  },
  open: function (content, callback) {
    this.config.content = content
    this.config.success = callback;
    this.common(this.config);
  },
  modal: function (content, title = '注意', callback = ()=>{}) {
    wx.showModal({
      title: title,
      content: content,
      showCancel: false,
      success: function (res) {
        if (res.confirm && callback) {
          callback.apply();
        }
      }
    });
  },
  modalOk: function (content, callback) {
    wx.showModal({
      content: content,
      showCancel: false,
      success: function (res) {
        if (res.confirm && callback) {
          callback.apply();
        }
      }
    });
  },
  openExt: function (content, callback) {
    this.config.content = content
    this.config.success = function (res) {
      if (res.confirm) {
        callback.apply();
      }
    };
    this.common(this.config);
  },
};
let toast = {
  config: {
    title: '已完成',
    icon: 'success',
    mask: true,
    duration: 3000
  },
  common: function (opt) {
    let changeOp = Object.assign({}, this.config, opt);
    wx.showToast(changeOp);
  },
  success: function (title) {
    this.config.title = title;
    this.common(this.config);
  },
  fail: function (msg = '未知异常', duration = 3) {
    wx.showToast({
      title: msg,
      mask: true,
      image: '/static/images/icon_error.png',
      duration: duration * 1000
    })
  },
  pure(msg = '未知异常', duration = 2) {
    wx.showToast({
      title: msg,
      icon: 'none',
      duration: duration * 1000
    });
  },
  loading: function (msg = '数据加载中', duration = 3) {
    wx.showToast({
      title: msg,
      mask: true,
      icon: 'loading',
      duration: duration * 1000
    });
  }
};

var upload = {
  single(file, fileName, url) {
    return new Promise(function (resolve, reject) {
      const uploadTask = wx.uploadFile({
        url: url,
        filePath: file,
        name: fileName,
        header: {
          'X-Rent-Token': wx.getStorageSync('token')
        },
        success: function (res) {
          var _res = JSON.parse(res.data);
          if (_res.errno == 0) {
            resolve(_res.data);
          } else {
            reject(_res.data);
          }
        },
        fail: function (e) {
          wx.showModal({
            title: '错误',
            content: '上传失败',
            showCancel: false
          })
        },
      });
      uploadTask.onProgressUpdate((res) => {
        console.log('上传进度', res.progress)
        console.log('已经上传的数据长度', res.totalBytesSent)
        console.log('预期需要上传的数据总长度', res.totalBytesExpectedToSend)
      })
    })
  },
  mutiles(files, fileName, url, arr = []) {
    var that = this;
    return new Promise(function (resolve, reject) {
      if (files.length > 0) {
        that.single(files[0], fileName, url).then(rsp => {
          arr.push(rsp);
          if (files.length > 1) {
            that.mutiles(files.slice(1), fileName, url, arr).then(rsp => {
              resolve(rsp);
            }).catch((err) => {
              reject(err);
            });
          } else {
            resolve(arr);
          }
        }).catch((err) => {
          reject(err);
        });
      } else {
        resolve(arr);
      }
    });
  },

};
var wxReq = {
  instatnce() {
    return new WxRequest({
      // `baseURL` 将自动加在 `url` 前面，除非 `url` 是一个绝对 URL。
      // 它可以通过设置一个 `baseURL` 便于为实例的方法传递相对 URL
      // 如 https://example.com/api/user
      baseURL: '',
      // `url` 是用于请求的服务器 URL
      url: '',
      // `method` 是创建请求时使用的方法，默认是 GET
      method: 'POST',
      // `dataType` 表示服务器响应的数据类型
      dataType: 'JSON',
      // `data` 是作为请求主体被发送的数据
      data: {},
      // `headers` 是即将被发送的自定义请求头
      header: {
        'Accept': 'application/json, text/plain, */*',
        'Content-Type': 'application/json',
        'X-Rent-Token': wx.getStorageSync('token')
      },
      // `transformRequest` 允许在向服务器发送前，转换请求数据
      transformRequest: [
        (data, header) => {
          return data
        },
      ],

      // `transformResponse` 转换响应数据
      transformResponse: [
        (data, header) => {
          if (typeof data === 'string') {
            try {
              data = JSON.parse(data)
            } catch (e) { /* Ignore */ }
          }
          return data
        },
      ],
      // 基于响应状态返回成功或失败
      validateStatus: status => status >= 200 && status < 300,
    });
  },
  init: function () {
    this.WxRequest = this.instatnce();
    this.WxReq = this.instatnce();
    this.interceptors();
    this.interceptorsPure();
  },
  interceptorsPure: function () {
    this
      .WxReq
      .interceptors.use({
        request(request) {
          return request
        },
        requestError(requestError) {
          wx.hideToast();
          wx.hideLoading();
          return Promise.reject(requestError)
        },
        response(response) {
          return response
        },
        responseError(responseError) {
          wx.hideToast();
          wx.hideLoading();
          return Promise.reject(responseError)
        },
      })
  },
  interceptors: function () {
    this
      .WxRequest
      .interceptors.use({
        request(request) {
          wx.showLoading({
            mask: true,
            title: '请求中...',
          })
          return request
        },
        requestError(requestError) {
          wx.hideLoading()
          return Promise.reject(requestError)
        },
        response(response) {
          wx.hideLoading()
          return response
        },
        responseError(responseError) {
          wx.hideLoading()
          return Promise.reject(responseError)
        },
      })
  },
  plugin: function () {
    this.init();
    return [this.WxRequest, this.WxReq];
  }
}

function loginAndGetUserInfo() {
  return new Promise(function (resolve, reject) {
    let code = null;
    return login().then((res) => {
      code = res.code;
      return getUserInfo();
    }).then((userInfo) => {
      //存储用户信息
      wx.setStorageSync('userInfo', userInfo);
      wx.setStorageSync('code', code);
      resolve(userInfo);
    }).catch((err) => {
      reject(err);
    });
  });
}

/**
 * 检查微信会话是否过期
 */
function checkSession() {
  return new Promise(function (resolve, reject) {
    wx.checkSession({
      success: function () {
        resolve(true);
      },
      fail: function () {
        reject(false);
      }
    })
  });
}

/**
 * 调用微信登录
 */
function login() {
  return new Promise(function (resolve, reject) {
    wx.login({
      success: function (res) {
        if (res.code) {
          wx.setStorageSync('code', res.code);
          resolve(res);
        } else {
          reject(res);
        }
      },
      fail: function (err) {
        reject(err);
      }
    });
  });
}

function getUserInfo() {
  return new Promise(function (resolve, reject) {
    wx.getUserInfo({
      withCredentials: true,
      success: function (res) {
        resolve(res);
      },
      fail: function (err) {
        reject(err);
      }
    })
  });
}

function getCheckUserInfo() {
  return new Promise(function (resolve, reject) {
    wx.getSetting({
      success: (res) => {
        if (res.authSetting['scope.userInfo'] != undefined && res.authSetting['scope.userInfo'] != true) {
          wx.openSetting({
            success: function (data) {
              if (data.authSetting["scope.userInfo"] == true) {
                resolve(getUserInfo());
              } else {
                toast.fail('授权失败');
              }
            }
          })
        } else if (res.authSetting['scope.userInfo'] == undefined) {
          wx.redirectTo({
            url: '/pages/auth/login/login',
          })
        } else {
          resolve(getUserInfo());
        }
      }
    })
  });
}
var clone = function (obj) {
  if (obj === null) return null
  if (typeof obj !== 'object') return obj;
  if (obj.constructor === Date) return new Date(obj);
  var newObj = new obj.constructor();  //保持继承链
  for (var key in obj) {
    if (obj.hasOwnProperty(key)) {   //不遍历其原型链上的属性
      var val = obj[key];
      newObj[key] = typeof val === 'object' ? clone(val) : val; // 使用arguments.callee解除与函数名的耦合
    }
  }
  return newObj;
};
var page = {
  config: {
    page: 1,
    limit: 10
  },
  hasLoad: true,
  isLoad: function (ls) {
    //console.log('lsssssssssssssss', ls);
    //是否还有下一页
    if (ls.length) {
      this.hasLoad = !(ls.length < this.config.limit);
    } else {
      if (Object.keys(ls).length) {
        this.hasLoad = !(Object.keys(ls).length < this.config.limit);
      } else {
        this.hasLoad = false;
      }
    }
    return this.hasLoad;
  },
  reset: function () {
    this.config.page = 1;
    this.hasLoad = true;
  },
  next: function () {
    this.config.page++;
  },
  clone() {
    var obj = this;
    if (typeof obj !== 'object') return obj;
    if (obj.constructor === Date) return new Date(obj);
    var newObj = new obj.constructor();  //保持继承链
    for (var key in obj) {
      if (obj.hasOwnProperty(key)) {   //不遍历其原型链上的属性
        var val = obj[key];
        newObj[key] = typeof val === 'object' ? clone(val) : val; // 使用arguments.callee解除与函数名的耦合
      }
    }
    return newObj;
  }
};
var $ = function () {
  var copyIsArray,
    toString = Object.prototype.toString,
    hasOwn = Object.prototype.hasOwnProperty,
    class2type = {
      '[object Boolean]': 'boolean',
      '[object Number]': 'number',
      '[object String]': 'string',
      '[object Function]': 'function',
      '[object Array]': 'array',
      '[object Date]': 'date',
      '[object RegExp]': 'regExp',
      '[object Object]': 'object'
    },
    type = function (obj) {
      return obj == null ? String(obj) : class2type[toString.call(obj)] || "object";
    },
    isWindow = function (obj) {
      return obj && typeof obj === "object" && "setInterval" in obj;
    },
    isArray = Array.isArray || function (obj) {
      return type(obj) === "array";
    },
    isPlainObject = function (obj) {
      if (!obj || type(obj) !== "object" || obj.nodeType || isWindow(obj)) {
        return false;
      }
      if (obj.constructor && !hasOwn.call(obj, "constructor")
        && !hasOwn.call(obj.constructor.prototype, "isPrototypeOf")) {
        return false;
      }
      var key;
      for (key in obj) {
      }
      return key === undefined || hasOwn.call(obj, key);
    },
    extend = function (deep, target, options) {
      for (name in options) {
        src = target[name];
        copy = options[name];
        if (target === copy) { continue; }
        if (deep && copy
          && (isPlainObject(copy) || (copyIsArray = isArray(copy)))) {
          if (copyIsArray) {
            copyIsArray = false;
            clone = src && isArray(src) ? src : [];
          } else {
            clone = src && isPlainObject(src) ? src : {};
          }
          target[name] = extend(deep, clone, copy);
        } else if (copy !== undefined) {
          target[name] = copy;
        }
      }
      return target;
    };
  return { extend: extend };
}();
/**
 * 时间格式化处理
 * yyyy-MM-dd HH:mm:ss
 */
function dateFtt(fmt, date) {
  var o = {
    "M+": date.getMonth() + 1,                 //月份   
    "d+": date.getDate(),                    //日   
    "h+": date.getHours(),                   //小时   
    "m+": date.getMinutes(),                 //分   
    "s+": date.getSeconds(),                 //秒   
    "q+": Math.floor((date.getMonth() + 3) / 3), //季度   
    "S": date.getMilliseconds()             //毫秒   
  };
  if (/(y+)/.test(fmt))
    fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
  for (var k in o)
    if (new RegExp("(" + k + ")").test(fmt))
      fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
  return fmt;
}
function isValidPhone(str) {
  var myreg = /^[1][3,4,5,7,8][0-9]{9}$/;
  if (!myreg.test(str)) {
    return false;
  } else {
    return true;
  }
}

/*获取当前页url*/
function getCurrentPageUrl() {
  var pages = getCurrentPages()    //获取加载的页面
  var currentPage = pages[pages.length - 1]    //获取当前页面的对象
  var url = currentPage.route    //当前页面url
  return url
}

/*获取当前页带参数的url*/
function getCurrentPageUrlWithArgs() {
  var pages = getCurrentPages()    //获取加载的页面
  var currentPage = pages[pages.length - 1]    //获取当前页面的对象
  var url = currentPage.route    //当前页面url
  var options = currentPage.options    //如果要获取url中所带的参数可以查看options

  //拼接url的参数
  var urlWithArgs = url + '?'
  for (var key in options) {
    var value = options[key]
    urlWithArgs += key + '=' + value + '&'
  }
  urlWithArgs = urlWithArgs.substring(0, urlWithArgs.length - 1)

  return urlWithArgs
}

/*获取当前页带参数的url*/
function getCurrentPageArgs() {
  var pages = getCurrentPages()    //获取加载的页面
  var currentPage = pages[pages.length - 1]    //获取当前页面的对象
  var url = currentPage.route    //当前页面url
  var options = currentPage.options    //如果要获取url中所带的参数可以查看options
  return options
}

/*url参数转换*/
function getArgs(p) {
  //拼接url的参数
  var obj = {};
  if (p.indexOf('&') != -1 && p.indexOf('=') != -1) {
    p.split('&').forEach(function (i, n) {
      var temp = i.split('=');
      obj[temp[0]] = temp[1];
    });
  }
  return obj
}

/*url参数转换*/
function getUrlWithArgs(options) {
  //拼接url的参数
  var urlWithArgs = '';
  for (var key in options) {
    var value = options[key]
    urlWithArgs += key + '=' + value + '&'
  }
  urlWithArgs = urlWithArgs.substring(0, urlWithArgs.length - 1)

  return urlWithArgs
}

/**
 * 封封微信的的request
 */
function request(url, data = {}, method = "GET", jumpPage = '') {
  return new Promise(function (resolve, reject) {
    wx.request({
      url: url,
      data: data,
      method: method,
      header: {
        'Content-Type': 'application/json',
        'X-Rent-Token': wx.getStorageSync('token')
      },
      success: function (res) {
        console.log("success");
        wx.hideLoading();
        if (res.statusCode == 200) {

          if (res.data.errno == 401) {
            var msg = "请先登录后操作!";
            if (wx.getStorageSync('phoneNumber') && wx.getStorageSync('token')) {
              msg = "登录状态失效,请重新登录！";
            }
            //需要登录后才可以操作
            confirm.openExt(msg, function () {
              wx.clearStorage();
              var p = encodeURIComponent(getCurrentPageUrlWithArgs());
              wx.redirectTo({
                url: '/pages/auth/login/login?page=' + p,
              })
              reject({ msg: msg, isLogin: true });
            });
          } else {
            resolve(res.data);
          }
        } else {
          reject(res.errMsg);
        }

      },
      fail: function (err) {
        wx.hideLoading();
        reject(err)
      }
    })
  });
}

/** 判断对象是否为空 */
function isNullOrEmpty(obj) { return (obj == null || obj == undefined || obj.toString().replace(/(^s*)|(s*$)/g, "").length == 0); };

/** 判断对象是否为数组*/
function isArray(obj) { return Object.prototype.toString.apply(obj) === '[object Array]'; };
module.exports = {
  formatTime,
  generateUUID,
  request,
  checkSession,
  login,
  getUserInfo,
  arrayUtil,
  dateUtil,
  confirm,
  toast,
  wxReq,
  loginAndGetUserInfo,
  getCheckUserInfo,
  page,
  dateFtt,
  upload,
  clone,
  isValidPhone,
  isNullOrEmpty,
  isArray,
  getCurrentPageUrl,
  getCurrentPageUrlWithArgs,
  getUrlWithArgs,
  getCurrentPageArgs,
  getArgs,
  $
}